#ifndef _NIVEAU_H_
#define _NIVEAU_H_

#include "Heros.h"
#include "Boss.h"
#include "TabEnnemis.h"
#include "TabTirs.h"
#include "TabBonus.h"
#include "Collision.h"
#include "Profil.h"


/** @brief File brief description
 Le fichier Niveau.h contient la declaration de toutes les fonctions et procedures necessaires
à la gestion d'un tour de jeu sur un terrain donne (creation et initialisation du niveau (on definit 
quel est le heros qui et ou sont les ennemis, quel est le terrain...).Une procedure importante est
niveauEvolution qui definit ce qui doit se passer pour un tour de jeu*/


typedef enum {facile, moyen, difficile, extreme} Difficulte;

/** @brief La structure niveau est complexe. Elle comporte le score du joueur (un entier), la position de debut et de fin
 de la fenetre de vue,un tableau de pointeurs de terrains qui contient des pointeurs sur tous les terrains du jeu,
 un pointeur sur le boss du terrain en cours, un pointeur sur le hero.Les trois champs suivants sont 3 tableaux de pointeurs,
 pointeurs d'ennemis, de tirs puis de bonus, puis le nombres d'ennemis dans le tableau (et donc du terrain en cours),
 et enfin le numéro du niveau suivant ainsi que celui actuel et la difficulté du niveau et la vitesse de defilement de la fenetre*/
typedef struct {
	int score_niveau;
	float posY_debut_fenetre;		//haut de la fenetre
	float posY_fin_fenetre;			//bas de la fenetre
	Terrain* pterrains;
	Boss* pboss;
	Heros* phero;
	TabEnnemis* ptab_pennemis;
	TabTirs* ptab_ptirs;
	TabBonus* ptab_pbonus;
	int nbre_ennemis;
	int num_niveau_actuel;
	int num_niveau_suivant;
	Difficulte difficulte;
	float defilement;
} Niveau;

/** @brief Cette procedure initialise un Niveau en saisissant toutes ses caracteristiques
 * @param [in] pterrain
 * @param [in] pbos
 * @param [in] pheros
 * @param [in] ptab_pennemiss
 * @param [in] ptab_ptirss
 * @param [in] ptab_bonuss
 * @return pniveau*/
Niveau* creerNiveau (Terrain* pterrain, Boss* pbos, Heros* pheros, TabEnnemis* ptab_pennemiss, 
		     TabTirs* ptab_ptirss, TabBonus* ptab_bonuss);

/** @brief Cette fonction reserve dans le tas l'epace necessaire pour un niveau,
 * initialise ses champs et retourne le pointeur créé
 * @param [in,out] pniveau
 * @param [in] pterrain
 * @param [in] pbos
 * @param [in] pheros
 * @param [in] ptab_pennemiss
 * @param [in] ptab_ptirss
 * @param [in] ptab_bonuss*/
void initNiveau (Niveau* pniveau, Terrain* pterrain, Boss* pbos, Heros* pheros,
		 TabEnnemis* ptab_pennemiss, TabTirs* ptab_ptirss, TabBonus* ptab_bonuss);

/** @brief Cette procédure libere l'espace memoire alloué pour le terrain, le boss, le heros
 * le tableau d'ennemis/ de tir/ de bonus
 * @param [in,out] pniveau*/
void libereNiveau (Niveau* pniveau);

/** @brief Cette procédure libere l'espace mémoire alloué pour le niveau
 * @param [in,out] ppniveau*/
void detruireNiveau (Niveau** ppniveau);

/** @brief Cette fonction retourne le pointeur du terrain du niveau
 * @param [in] pniveau*/
Terrain* niveauGetTerrainPtr(Niveau* pniveau);

/** @brief Cette fonction retourne le pointeur du heros du niveau
 * @param [in] pniveau*/
Heros* niveauGetHerosPtr(Niveau* pniveau);

/** @brief Cette fonction retourne le pointeur du boss du niveau
 * @param [in] pniveau*/
Boss* niveauGetBossPtr(const Niveau* pniveau);

/** @brief Cette fonction retourne le pointeur de l'ennemi en position i_ennemi dans le tableau d'ennemis
 * @param [in] pniveau
 * @param [in] i_ennemi
 * @return pniveau->ptab_pennemis->ptab_ennemis[i_ennemi]*/
Ennemi* niveauGetEnnemiPtr(const Niveau* pniveau, const int i_ennemi);

/** @brief Cette fonction retourne le pointeur du tir en position i_tir dans le tableau de tirs
 * @param [in] pniveau
 * @param [in] i_tir
 * @return pniveau->ptab_ptirs->ptab_tirs[i_tir]*/
Tir* niveauGetTirPtr(const Niveau* pniveau, const int i_tir);

/** @brief Cette fonction retourne le pointeur du bonus en position i_bonus dans le tableau de bonus
 * @param [in] pniveau
 * @param [in] i_bonus
 * @return pniveau->ptab_pbonus->ptab_bonus[i_bonus]*/
Bonus* niveauGetBonusPtr(const Niveau* pniveau, const int i_bonus);

/** @brief Cette fonction retourne le pointeur du terrain du niveau, cette fois ci constant pour uniquement les comparaisons
 * @param [in] pniveau*/
const Terrain* niveauGetConstTerrainPtr(const Niveau* pniveau);

/** @brief Cette fonction retourne le pointeur du heros du niveau, cette fois ci constant pour uniquement les comparaisons
 * @param [in] pniveau*/
const Heros* niveauGetConstHerosPtr(const Niveau* pniveau);

/** @brief Cette fonction retourne le pointeur du boss du niveau, cette fois ci constant pour uniquement les comparaisons
 * @param [in] pniveau*/
const Boss* niveauGetConstBossPtr(const Niveau* pniveau);

/** @brief Cette fonction retourne le score du niveau passé en parametre
 * @param [in] pniveau
 * @return pniveau->score_niveau*/
const int getScoreNiveau (const Niveau* pniveau);

/** @brief Cette procédure permet de changer le score du niveau passé en parametre par score
 * @param [in,out] pniveau
 * @param [in] score*/
void setScoreNiveau (Niveau* pniveau, const int score);

/** @brief Cette fonction retourne le nombre d'ennemis du niveau passé en parametre
 * @param [in] pniveau
 * @return pniveau->ptab_pennemis->nbre_ennemis*/
const int getNbreEnnemis (const Niveau* pniveau);

/** @brief Cette fonction retourne le nombre de tirs du niveau passé en parametre
 * @param [in] pniveau
 * @return pniveau->ptab_ptirs->nbre_tirs*/
const int getNbreTirs (const Niveau* pniveau);

/** @brief Cette fonction retourne le nombre de bonus du niveau passé en parametre
 * @param [in] pniveau
 * @return pniveau->ptab_pbonus->nbre_bonus*/
const int getNbreBonus (const Niveau* pniveau);

/** @brief Cette fonction retourne le numéro du niveau passé en parametre
 * @param [in] pniveau
 * @return pniveau->ptab_pennemis->nbre_ennemis*/
const int getNumNiveauActuel (const Niveau* pniveau);

/** @brief Cette procédure permet de modifer le numéro du niveau actuel par num_niveau
 * @param [in,out] pniveau
 * @param [in] num_niveau*/
void setNumNiveauActuel (Niveau* pniveau, const int num_niveau);

/** @brief Cette fonction retourne la vitesse de defilement de la fenetre du niveau
 * @param [in] pniveau
 * @return pniveau->defilement
 */
const float getDefilementNiveau (const Niveau* pniveau);

/** @brief Cette procedure permet de modifier la vitesse de defilement de la
 * fenetre du niveau
 * @param [in,out] pniveau
 * @param [in] defil
 */
void setDefilementNiveau (Niveau* pniveau, const float defil);

/** @brief Cette fonction retourne le numero du niveau après celui passé en parametre
 * @param [in] pniveau
 * @return pniveau->num_niveau_suivant*/
const int getNumNiveauSuivant (const Niveau* pniveau);

/** @brief Cette fonction retourne la difficulté du niveau passé en parametre
 * @param [in] pniveau
 * @return pniveau->difficulte*/
const int getDifficulteNiveau (const Niveau* pniveau);

/** @brief Cette procédure permet de changer la difficulté du niveau pasé en parametre par difficult
 * @param [in,out] pniveau
 * @param [in] difficult*/
void setDifficulteNiveau (Niveau* pniveau, const Difficulte difficult);

/** @brief Cette procédure permet d'augmenter le score du niveau passé en parametre avec ajout
 * @param [in,out] pniveau
 * @param [in] ajout*/
void augmenterScoreNiveau (Niveau* pniveau, const int ajout);

/** @brief Cette procédure permet de gerer l'action du joueur (tirer, bouger)
 * @param [in,out] pniveau
 * @param [in] touche_clavier*/
void niveauActionClavierSouris (Niveau* pniveau, char touche_clavier);

/** @brief Cette procédure permet de gerer une évolution d'un niveau
 * @param [in,out] pniveau*/
void niveauEvolution (Niveau* pniveau);

/** @brief Cette fonction permet la création d'un niveau jouable (positionnement des ennemis avec leurs trajectoires, ajout du boss)
 * retourne le pointeur du niveau créé
 * @return pniveau*/
Niveau* creerNiveauBenou1 ();

/** @brief Cette fonction permet la création d'un niveau jouable (positionnement des ennemis avec leurs trajectoires, ajout du boss)
 * retourne le pointeur du niveau créé
 * @return pniveau*/
Niveau* creerNiveauBenou2 ();

/** @brief Cette fonction permet la création d'un niveau jouable (positionnement des ennemis avec leurs trajectoires, ajout du boss)
 * retourne le pointeur du niveau créé
 * @return pniveau*/
Niveau* creerNiveauBenou3 ();

/** @brief Cette fonction permet la création d'un niveau jouable (positionnement des ennemis avec leurs trajectoires, ajout du boss)
 * retourne le pointeur du niveau créé
 * @return pniveau*/
Niveau* creerNiveauBenou4 ();

/** @brief Cette fonction permet la création d'un niveau jouable (positionnement des ennemis avec leurs trajectoires, ajout du boss)
 * retourne le pointeur du niveau créé
 * @return pniveau*/
Niveau* creerNiveauBenou5 ();

/** @brief Cette fonction permet la création d'un niveau jouable (positionnement des ennemis avec leurs trajectoires, ajout du boss)
 * retourne le pointeur du niveau créé
 * @return pniveau*/
Niveau* creerNiveauSurvivor ();

#endif
